<script setup lang="ts">
import { ref, onMounted, computed, nextTick, Ref } from 'vue';
import useStore from '@/stores';
import { useRouter } from 'vue-router';
import { traduction } from '@/utils/language';
import { OChart, OChartLayout } from '@computing/opendesign2';
import {
  getPowerEnergy,
  getThermals,
  getPower,
  renderPredictedPower,
  renderPower,
  renderGaugeChart,
  getPowerControl,
} from '../../services/power.services';
import { IconRemind, IconX } from '@computing/opendesign-icons';
import { loading, getStoreData } from '@/utils/composition';
import { LineChart, GaugeChart, PieChart } from 'echarts/charts';
import {
  GridComponent,
  LegendComponent,
  MarkLineComponent,
  TooltipComponent,
  VisualMapComponent,
} from 'echarts/components';
import * as echarts from 'echarts/core';
import '@/assets/common/style/echarts-formatter-style/index.scss';
import TableNoData from '@/components/TableNoData/TableNoData.vue';
enum Policies {
  ENERGYSAVING = 'EnergySaving',
  LOWNOISE = 'LowNoise',
  HIGHPERFORMANCE = 'HighPerformance',
  CUSTOM = 'Custom',
  MPC = 'MPC',
  LOADBALANCING = 'LoadBalancing',
  ACTIVESTANDBY = 'Active/Standby',
  DEEPSLEEP = 'DeepSleep',
}
const store = useStore();
const $router = useRouter();
const show = ref(true);
const noData = ref(true);
const lastStartTime = ref('');
const locale = store.state.loct.locale;
// 节能收益开关是否开启
const status = ref<boolean | null>(null);
const total = ref<number | null>(null);
const haveChartData = ref(false);
const isRack = ref(false);
const measurement = ref<{
  // 历史平均功率
  HistoryPowerAverageWatts: number;
  // 开启节能功能后预计节省功耗
  PredictedPowerSavedKwh: number;
  // 累计节省功耗
  TotalPowerSavedKwh: number;
  // 开启MPC时间
  LastEnabledTime: string;
  // 状态
  PowerPredictStatus: string;
  // 整机、风扇、电源的节能状态
  PolicyGuidance: any;
}>();
interface ChartElement extends Element {
  resize: () => void;
  update: (opt: any, notMerge?: boolean) => void;
}
const coms = [PieChart, GaugeChart, GridComponent, TooltipComponent];
const components = [
  LineChart,
  GridComponent,
  TooltipComponent,
  VisualMapComponent,
  MarkLineComponent,
  LegendComponent,
];
const EXCELLENT = 80;
const GOOD = 60;
// 整机节能统计
const chassisHealthPercent = ref(0);

const defaultStatus = [
  {
    id: 'fan',
    title: traduction('HOME_FAN'),
    section: [
      {
        key: traduction('COMPONENT_ENERGY_SAVING_HEALTH'),
        value: 0,
      },
      {
        key: traduction('RECOMMENDATION_POLICY'),
        value: [],
      },
      {
        key: traduction('ENERGY_SAVING_SWITCH'),
        value: false,
      },
    ],
  },
  {
    id: 'switch',
    title: traduction('HOME_POWER'),
    section: [
      {
        key: traduction('COMPONENT_ENERGY_SAVING_HEALTH'),
        value: 0,
      },
      {
        key: traduction('RECOMMENDATION_POLICY'),
        value: [],
      },
      {
        key: traduction('ENERGY_SAVING_SWITCH'),
        value: false,
      },
    ],
  },
];

// 节能功能状态
const funStatus = ref<any[]>([]);
const loadingData = ref(true);
const loadingData2 = ref(true);
const option = ref({});
const options = ref({});

const policiesTextMapping = new Map<Policies, string>([
  [Policies.ENERGYSAVING, 'FAN_MODEL_TITLE1'],
  [Policies.LOWNOISE, 'FAN_MODEL_TITLE2'],
  [Policies.HIGHPERFORMANCE, 'FAN_MODEL_TITLE3'],
  [Policies.CUSTOM, 'FAN_MODEL_TITLE4'],
  [Policies.MPC, 'MPCMODE'],
  [Policies.LOADBALANCING, 'POWER_LOAD_BALANCING'],
  [Policies.ACTIVESTANDBY, 'POWER_MAIN_STANDBY'],
]);

const themeMode = computed(() => {
  return store.state.loct.systemTheme;
});
const gaugeChart: Ref<ChartElement | null> = ref(null);
const powerChart = ref();
const predictedChart = ref();
const historyPowerList = ref([]);
function close(): void {
  show.value = false;
}
function isEqual(a: Array<string>, b: Array<string>) {
  return a.length === b.length && a.sort().toString() === b.sort().toString();
}
function initStatus(res: Array<any>): void {
  const ready = 'Normal';
  const data = res[1].data;
  measurement.value = data.Measurement || {};
  let chassis = measurement.value?.PolicyGuidance?.find((v: any) => v.Component === 'Chassis');
  let fan = measurement.value?.PolicyGuidance?.find((v: any) => v.Component === 'Fan');
  let power = measurement.value?.PolicyGuidance?.find((v: any) => v.Component === 'PSU');
  if (chassis) {
    chassisHealthPercent.value = chassis?.HealthPercent;
  }

  const fanObj = defaultStatus.filter(item => item.id === 'fan')[0];
  const powerObj = defaultStatus.filter(item => item.id === 'switch')[0];

  isRack.value = res[3]?.data?.ChassisType === 'Rack';
  if (isRack.value) {
    funStatus.value = [powerObj];
  } else {
    funStatus.value = [...defaultStatus];
  }

  // 设置风扇节能状态显示
  if (fan) {
    fanObj.section[2].value = fan?.RecommendedPolicies?.length === 0 ? false : isEqual(
      fan?.CurrentPolicies || [],
      fan?.RecommendedPolicies || [],
    );
    fanObj.section[0].value = fan?.HealthPercent;
    fanObj.section[1].value = fan?.RecommendedPolicies;
  }
  // 设置电源节能状态显示
  if (power) {
    powerObj.section[2].value = power?.RecommendedPolicies?.length === 0 ? false : isEqual(
      power?.CurrentPolicies || [],
      power?.RecommendedPolicies || [],
    );
    powerObj.section[0].value = power?.HealthPercent;
    powerObj.section[1].value = power?.RecommendedPolicies;
  }
  // 判断是否开启节能状态（风扇或电源节能状态有一个开启即可）
  status.value = funStatus.value.map(item => item.section[0].value).some(v => v);
  lastStartTime.value = measurement.value?.LastEnabledTime || '';
  noData.value = measurement.value?.PowerPredictStatus !== ready;
  const totalValue = status.value
    ? measurement.value?.TotalPowerSavedKwh
    : measurement.value?.PredictedPowerSavedKwh;
  total.value = typeof totalValue === 'number' ? totalValue : null;
}
function initPredictedChart(res: any): void {
  const powerList = (res[1].data.PredictedPowerData || []).map((e: any) => ({
    time: e.Time,
    value: e.PredictedPowerWatts,
  }));
  const savedList = (res[1].data.PredictedPowerSavedData || []).map((e: any) => ({
    time: e.Time,
    value: e.PredictedPowerSavedWatts === null ? '--' : e.PredictedPowerSavedWatts,
  }));
  const predictedOptions = renderPredictedPower(
    traduction('POWER_UNIT'),
    powerList,
    savedList,
    echarts,
  );
  loadingData2.value = false;
  predictedChart.value?.update(predictedOptions, true);
  nextTick(() => {
    predictedChart.value?.resize();
  });
}

function initEnergyChart(res: any): void {
  historyPowerList.value = (res[2].data.History || []).filter((e: any) => {
    return (lastStartTime.value || '').localeCompare(e.Time) === -1;
  });
  const powerList = historyPowerList.value.map((e: any) => ({
    time: e.Time,
    value: e.PowerWatts,
  }));
  const series2List = powerList.map(e => ({
    time: e.time,
    value:
      measurement.value?.HistoryPowerAverageWatts === null
        ? '--'
        : measurement.value?.HistoryPowerAverageWatts,
  }));
  const chartOptions = renderPower(traduction('POWER_UNIT'), powerList, series2List, echarts);
  loadingData2.value = false;
  powerChart.value?.update(chartOptions, true);
  nextTick(() => {
    powerChart.value?.resize();
  });
}

function initGaugeChart(res: { data: Array<{ value: number }> }) {
  let gaugeOptions = renderGaugeChart(res.data, traduction('POWER_ENERGY_STATISTICS'));
  loadingData.value = false;
  gaugeChart.value?.update(gaugeOptions, true);
}
function init(): void {
  loading(true);
  Promise.all([getThermals(), getPowerEnergy(), getPower(), getPowerControl()])
    .then(res => {
      loading(false);
      initStatus(res);
      initGaugeChart({
        data: [
          {
            value: chassisHealthPercent.value,
          },
        ],
      });
      if (status.value) {
        initEnergyChart(res);
      } else {
        initPredictedChart(res);
      }
    })
    .catch(() => {
      loading(false);
    });
}
function redirect(id: string, page?: string): void {
  if (id === 'fan') {
    $router.push(`/navigate/system/fans/fans-info?page=${page}`);
  } else {
    $router.push('/navigate/system/power/info');
  }
}

function getStrategyText(value: string): string {
  if (policiesTextMapping.has(value as any)) {
    return policiesTextMapping.get(value as Policies) as string;
  } else if (value.includes(Policies.DEEPSLEEP)) {
    return traduction('FAN_MODEL_DEEPSLEEP', [value.match(/\d+/g)?.[0]]);
  } else {
    return '';
  }
}

const powerSupplySupported = computed(() => getStoreData('loct', 'powerSupplySupported'));
const fansSupported = computed(() => getStoreData('loct', 'fanspt'));
onMounted(() => {
  init();
});
</script>

<template>
  <div v-if="show" class="remindDiv">
    <div class="remindIcon">
      <el-icon size="16">
        <IconRemind />
      </el-icon>
    </div>
    <div class="remindContent">
      {{ $t('POWER_ENERGY_TIP') }}
    </div>
    <el-icon id="closeTipIcon" class="close-icon" size="16" @click="close()">
      <IconX />
    </el-icon>
  </div>
  <div class="info">
    <div id="energy-static">
      <h2>{{ traduction('SYSTEM_ENERGY_SAVING_STATISTICS') }}</h2>
      <section>
        <div class="pie-chart">
          <o-chart-layout v-loading="loadingData" class="chart-card">
            <o-chart
              ref="gaugeChart"
              class="demo-chart"
              :option="option"
              :theme="themeMode"
              :components="coms"
            ></o-chart>
          </o-chart-layout>
        </div>
        <div class="health item">
          <h4>{{ traduction('ENERGY_SAVING_HEALTH') }}</h4>
          <el-tooltip placement="top">
            <template #content>
              <span v-if="![0, null].includes(chassisHealthPercent)">
                {{
                  chassisHealthPercent > GOOD
                    ? chassisHealthPercent > EXCELLENT
                      ? traduction('EXECLLENT')
                      : traduction('GOOD')
                    : traduction('GENERAL')
                }}
              </span>
              <span v-else>--</span>
            </template>
            <el-tag
              v-if="![0, null].includes(chassisHealthPercent)"
              :class="{
                general: chassisHealthPercent <= GOOD,
                good: chassisHealthPercent > GOOD,
                excellent: chassisHealthPercent > EXCELLENT
              }"
              size="large"
            >
              {{
                chassisHealthPercent > GOOD
                  ? chassisHealthPercent > EXCELLENT
                    ? traduction('EXECLLENT')
                    : traduction('GOOD')
                  : traduction('GENERAL')
              }}
            </el-tag>
            <span v-else class="consumption-value">--</span>
          </el-tooltip>
        </div>
        <div class="consumption item">
          <h4>
            {{
              status ? traduction('ACCUMULATED_POWER_SAVINGS') : traduction('POWER_ESTIMATED_W_OFF')
            }}
          </h4>
          <div class="consumption-value">{{ total === null ? '--' : total }}</div>
        </div>
      </section>
    </div>
    <div id="fun-status">
      <h2>{{ $t('POWER_ENERGY_STATUS') }}</h2>
      <div v-for="item in funStatus" :key="item.id" class="fun-status-content">
        <h3>{{ item.title }}</h3>
        <div class="section">
          <div class="icon">
            <img
              v-if="item.id === 'fan'"
              class="img"
              src="@/assets/common/image/fan.svg"
              :title="item.title"
            />
            <img v-else class="img" src="@/assets/common/image/power.svg" :title="item.title" />
          </div>
          <div class="mid">
            <div v-for="(word, idx) in item.section" :key="idx" class="mid-item">
              <div class="label" :class="{ 'other-lang': locale !== 'zh' }">
                <el-tooltip placement="top">
                  <template #content>
                    <div class="o-tooltip-wrap">
                      {{ word.key }}
                    </div>
                  </template>
                  {{ word.key }}
                </el-tooltip>
              </div>
              <div v-if="idx === 2" class="val">
                <el-tag size="small" :type="word.value ? 'success' : 'info'">
                  {{ word.value ? $t('POWER_ENERGY_STATUS_ON') : $t('POWER_ENERGY_STATUS_OFF') }}
                </el-tag>
                <el-tooltip v-if="item.id === 'fan' && fansSupported" placement="top">
                  <template #content>
                    {{ $t('POWER_ENERGY_STATUS_REDIRECT') }}
                  </template>
                  <span
                    v-if="item.id === 'fan' && fansSupported"
                    :id="`${item.id}-link`"
                    class="redirectHref"
                    @click="redirect(item.id, 'FAN_SET_TAB')"
                  >
                    {{ $t('POWER_ENERGY_STATUS_REDIRECT') }}
                  </span>
                </el-tooltip>
                <el-tooltip v-if="item.id === 'switch' && powerSupplySupported && !isRack" placement="top">
                  <template #content>
                    {{ $t('POWER_ENERGY_STATUS_REDIRECT') }}
                  </template>
                  <span
                    v-if="item.id === 'switch' && powerSupplySupported"
                    :id="`${item.id}-link`"
                    class="redirectHref"
                    @click="redirect(item.id)"
                  >
                    {{ $t('POWER_ENERGY_STATUS_REDIRECT') }}
                  </span>
                </el-tooltip>
              </div>
              <div v-if="idx === 0" class="val">
                <template v-if="word.value === 0">
                  <span class="empty-value">--</span>
                </template>
                <template v-else>
                  <span class="val-num mr-8">{{ word.value }}</span>
                  <el-tag
                    size="small"
                    :class="{
                      general: +word.value <= GOOD,
                      good: +word.value > GOOD,
                      excellent: +word.value > EXCELLENT
                    }"
                    class="num-tag"
                  >
                    {{
                      +word.value > GOOD
                        ? +word.value > EXCELLENT
                          ? traduction('EXECLLENT')
                          : traduction('GOOD')
                        : traduction('GENERAL')
                    }}
                  </el-tag>
                </template>
              </div>
              <div v-if="idx === 1" class="val">
                <span v-if="word.value && !word.value?.length" class="empty-value">--</span>
                <template v-else>
                  <span v-for="(v, i) in word.value" :key="i" class="advice">
                    <span>{{ $t(getStrategyText(v)) }}</span>
                    <el-divider
                      v-if="i !== (word.value as any).length - 1"
                      class="console-divider"
                      direction="vertical"
                    ></el-divider>
                  </span>
                </template>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- 节能功率统计曲线 -->
  <div v-if="status === null" class="no-data-container">
    <TableNoData />
  </div>
  <div v-show="status === true" class="page-bottom">
    <div id="energyStatistic">
      <div class="title">{{ $t('POWER_ENERGY_STATISTIC') }}</div>
    </div>
    <div v-show="historyPowerList.length" id="powerChart" class="chart-container">
      <o-chart-layout v-loading="loadingData2" class="line-chart-card">
        <o-chart
          ref="powerChart"
          class="demo-chart1"
          :option="options"
          theme="light"
          :components="components"
        ></o-chart>
      </o-chart-layout>
    </div>
    <div v-show="!historyPowerList.length" class="no-data-container">
      <TableNoData />
    </div>
  </div>
  <div v-show="status === false" class="page-bottom">
    <div id="energyStatistic">
      <div class="title">{{ $t('POWER_ENERGY_STATISTIC_OFF') }}</div>
    </div>
    <div v-show="!noData" id="predictedPowerChart" class="chart-container">
      <o-chart-layout v-loading="loadingData2" class="line-chart-card">
        <o-chart
          ref="predictedChart"
          class="demo-chart1"
          :option="options"
          theme="light"
          :components="components"
        ></o-chart>
      </o-chart-layout>
    </div>
    <div v-show="noData" class="no-data-container">
      <TableNoData />
    </div>
  </div>
</template>

<style lang="scss" scoped>
.remindDiv {
  display: flex;
  margin-bottom: 16px;
  background-color: var(--o-color-state-primary-secondary);
  height: 32px;
  align-items: center;
  padding-left: 16px;
  border-radius: 4px;
  width: calc(100% - 24px);
  position: relative;
  .remindIcon {
    height: 16px;
    line-height: 16px;
  }
  .remindContent {
    padding-left: 8px;
    padding-right: 8px;
  }
  .close-icon {
    position: absolute;
    right: 10px;
    cursor: pointer;
    &:hover {
      color: var(--o-color-primary-secondary);
    }
  }
}
.no-data-container {
  width: 100%;
  height: 245px;
  text-align: center;
  background-color: var(--o-bg-color-base);
  display: flex;
  flex-flow: column;
  justify-content: center;
}
.page-top,
.page-bottom {
  background-color: var(--o-bg-color-base);
  border-radius: 4px;
  padding: 24px;
  margin-bottom: 16px;
  margin-right: 24px;
  .title {
    font-size: 16px;
    font-weight: 600;
    color: var(--o-text-color-primary);
    line-height: 24px;
    margin-bottom: 16px;
  }
  .chart-container {
    height: 450px;
    width: 100%;
    min-width: 800px;
    .line-chart-card {
      width: 100%;
      height: 450px;
      padding: 0;
      .demo-chart1 {
        width: 100%;
        height: 450px;
      }
    }
    .chart {
      height: 450px;
      width: 100%;
      min-width: 800px;
    }
  }
}

.redirectHref {
  display: inline-block;
  color: #3291fe;
  font-weight: 500;
  letter-spacing: 0;
  text-align: center;
  line-height: 16px;
  cursor: pointer;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-left: 8px;
  overflow: hidden;
  vertical-align: sub;
  max-width: calc(100% - 95px);
}
.info {
  display: flex;
  flex-shrink: 0;
  gap: 16px;
  margin-bottom: 16px;
  margin-right: 24px;
}
.mr-8 {
  margin-right: 8px;
}
.common {
  .el-tag {
    min-width: 32px !important;
    &.general {
      background-color: #ebaf00 !important;
    }
    &.good {
      background-color: var(--o-color-primary) !important;
    }
    &.excellent {
      background-color: var(--o-color-success) !important;
    }
  }
  .el-tag--large {
    padding: 4px 20px !important;
  }
  background-color: var(--o-color-white);
  border-radius: 4px;
  padding: 24px;
  h2 {
    margin-bottom: 16px;
    font-weight: 600;
    font-size: 16px;
  }
}
#energy-static {
  @extend .common;
  flex-basis: 356px;
  section {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  .pie-chart {
    width: 100%;
    height: 225px;
    .chart-card {
      width: 100%;
      height: 100%;
      padding: 0 24px;
      .demo-chart {
        width: 100%;
        height: 220px;
      }
    }
  }
  .item {
    background: var(--o-bg-color-light);
    padding: 24px 16px;
    height: 56px;
    font-size: 14px;
    display: flex;
    flex-shrink: 0;
    align-items: center;
    border-radius: 4px;
    justify-content: space-between;
    h4 {
      font-weight: normal;
      flex-basis: 210px;
    }
    .consumption-value {
      font-size: 24px;
      font-weight: 600;
    }
  }
}
#fun-status {
  @extend .common;
  flex: 1;
  display: flex;
  flex-direction: column;
  h3 {
    font-size: 16px;
    margin-bottom: 4px;
  }
  .fun-status-content {
    background: var(--o-bg-color-light);
    padding: 24px;
    margin-bottom: 12px;
    border-radius: 4px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    &:last-child {
      margin-bottom: 0;
    }
  }
  .section {
    display: flex;
    gap: 24px;
    margin-left: -10px;
    align-items: center;
    .mid {
      flex: 1;
      div {
        font-size: 12px;
        color: var(--o-text-color-secondary);
      }
    }
    .mid-item {
      display: flex;
      align-items: center;
      margin-bottom: 13px;
      &:last-child {
        margin-bottom: 0;
      }
      .label {
        flex-basis: 150px;
        line-height: 24px;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
        &.other-lang {
          flex-basis: 200px;
          margin-right: 24px;
        }
      }
      .val {
        flex: 1;
        line-height: 20px;
        .val-num {
          font-size: 24px;
          font-weight: 600;
          color: var(--o-text-color-primary);
        }
        .num-tag {
          vertical-align: sub;
        }
        .advice {
          font-weight: 600;
          color: var(--o-text-color-primary);
        }
      }
    }
  }
}
.empty-value {
  font-size: 24px;
  font-weight: 600;
}
</style>
